import requests
import json
import time
import hashlib
import base64
import urllib.parse

from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.serialization import load_pem_private_key
from cryptography.hazmat.primitives.asymmetric.padding import PKCS1v15

# 配置信息
app_id = "wx499a94f9d35b7545"
mch_id = "1680751724"
api_v3_key = "Kangjin1234567891478523697896541"
private_key_path = "application/apps/cert/kg_apiclient_key.pem"
wx_notify_url = "https://127.0.0.1:8000/api/wx_notify"  # 微信支付异步通知回调地址
serial_no = "2D7E875B491709DF339566875F784040A1E04622"  # 商户证书序列号

# 加载私钥
with open(private_key_path, "rb") as f:
    private_key = load_pem_private_key(f.read(), password=None)

def generate_signature(method, url_path, timestamp, nonce_str, body):
    message = f"{method.upper()}\n{url_path}\n{timestamp}\n{nonce_str}\n{body}\n"
    signature = private_key.sign( data=message.encode(),
        padding=PKCS1v15(),
        algorithm=hashes.SHA256())
    return base64.b64encode(signature).decode()

def create_order(out_trade_no, amount, description, openid):
    url = "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi"
    timestamp = str(int(time.time()))
    nonce_str = "random_nonce_string"
    body = {
        "appid": app_id,
        "mchid": mch_id,
        "description": description,
        "notify_url": wx_notify_url,
        "out_trade_no": out_trade_no,
        "amount": {"total": amount, "currency": "CNY"},
        "payer": {"openid": openid}
    }
    body_json = json.dumps(body)
    signature = generate_signature("POST", "/v3/pay/transactions/jsapi", timestamp, nonce_str, body_json)
    headers = {
        "Content-Type": "application/json",
        "Accept": "application/json",
        "User-Agent": "your_user_agent",
        "Authorization": f'WECHATPAY2-SHA256-RSA2048 mchid="{mch_id}",nonce_str="{nonce_str}",signature="{signature}",timestamp="{timestamp}",serial_no="{serial_no}"'
    }
    response = requests.post(url, data=body_json, headers=headers)
    return response.json()

def get_payment_params(prepay_id):
    package_str = f"prepay_id={prepay_id}"
    timestamp = str(int(time.time()))
    nonce_str = "random_nonce_string_2"
    message = f"{app_id}\n{timestamp}\n{nonce_str}\n{package_str}\n"
    pay_sign = hashlib.sha256(message.encode()).hexdigest()
    return {
        "timeStamp": timestamp,
        "nonceStr": nonce_str,
        "package": package_str,
        "signType": "RSA",
        "paySign": pay_sign
    }

if   __name__ == '__main__':
    out_trade_no = "202109011010100001"
    amount = 1000
    description = "测试商品"
    openid = "oogzA68lRguok77ku-GCthpmqybM"
    response = create_order(out_trade_no, amount, description, openid)
    print(response)
    prepay_id = response["prepay_id"]
    payment_params = get_payment_params(prepay_id)
    print(payment_params)